/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * chatGraphPanel.java
 *
 * Created on 2010/5/6, 下午 05:16:17
 */
package chat;

import chat.mybean.*;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.util.AbstractMap.SimpleEntry;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.ImageIcon;
import javax.swing.JPanel;

/**
 *
 * @author spider391Tang
 */
public class chatGraphPanel extends javax.swing.JTextPane {


    public class ObjInfo
    {
        //String id = "";
        //Point pos = new Point(0,0);

        private Point pos = new Point(0, 0);

        /**
         * Get the value of pos
         *
         * @return the value of pos
         */
        public Point getPos() {
            return pos;
        }

        /**
         * Set the value of pos
         *
         * @param pos new value of pos
         */
        public void setPos(Point pos) {
            this.pos = pos;
        }

        private String id = "";

        /**
         * Get the value of id
         *
         * @return the value of id
         */
        public String getId() {
            return id;
        }

        /**
         * Set the value of id
         *
         * @param id new value of id
         */
        public void setId(String id) {
            this.id = id;
        }

    }
    /// 公子乖 -　參數 id 格式為: "使用者暱稱-流水編號"
    //           所以把 "使用者暱稱" parse 出來比對即可。
    private boolean isAuthor(String id) {
        //throw new UnsupportedOperationException("Not yet implemented");
        if (author == null) {
            return false;
        }

        String[] names = id.split("-");
        String cmd = names[0];
        if (cmd.compareTo(author) == 0) {
            return true;
        }

        return true;
    }

    public enum DragStatus {
        Draw,
        Choose,
        PointTo
    ,   Drag}
    private String author = null;
    private ObjInfo curObj = new ObjInfo();

    /**
     * Get the value of author
     *
     * @return the value of author
     */
    public String getAuthor() {
        return author;
    }

    /**
     * Set the value of author
     *
     * @param author new value of author
     */
    public void setAuthor(String author) {
        this.author = author;
    }
    private DragStatus status = DragStatus.PointTo;

    /**
     * Get the value of status
     *
     * @return the value of status
     */
    public DragStatus getStatus() {
        return status;
    }

    /**
     * Set the value of status
     *
     * @param status new value of status
     */
    public void setStatus(DragStatus status) {
        this.status = status;
        switch (status) {
            case Choose:
                setCursor(new java.awt.Cursor(java.awt.Cursor.CROSSHAIR_CURSOR));
                break;
            case Draw:
                setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR));
                break;
            case PointTo:
                setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
                break;
             case Drag:
                setCursor(new java.awt.Cursor(java.awt.Cursor.WAIT_CURSOR));
                break;
            default:
                break;
        }
    }
    /// 公子乖 -　更改原設計  Map<String,SimpleEntry<Point,MyBean>>
    //           因為在 paintComponent 時，若呼叫 getImage [getImage 含有 paint() 函式]
    //           會造成 null pointer exception
    //           推測原因:  wm_paint 訊息相衝突!?
    private Map<String, SimpleEntry<Point, SimpleEntry<MyBean, Image>>> beanMap = new LinkedHashMap<String, SimpleEntry<Point, SimpleEntry<MyBean, Image>>>();
    private int x = 0;

    /**
     * Get the value of beanMap
     *
     * @return the value of beanMap
     */
    public Map<String, SimpleEntry<Point, SimpleEntry<MyBean, Image>>> getBeanMap() {
        return beanMap;
    }
    private String beanName = null;

    /**
     * Get the value of beanName
     *
     * @return the value of beanName
     */
    public String getBeanName() {
        return beanName;
    }

    /**
     * Set the value of beanName
     *
     * @param beanName new value of beanName
     */
    public void setBeanName(String beanName) {
        this.beanName = beanName;
    }

    /** Creates new form chatGraphPanel */
    public chatGraphPanel() {
        initComponents();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        setFocusable(false);
        addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                formMouseClicked(evt);
            }
            public void mousePressed(java.awt.event.MouseEvent evt) {
                formMousePressed(evt);
            }
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                formMouseReleased(evt);
            }
        });
        addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                formMouseDragged(evt);
            }
            public void mouseMoved(java.awt.event.MouseEvent evt) {
                formMouseMoved(evt);
            }
        });
    }// </editor-fold>//GEN-END:initComponents

    /// 公子乖 -　在論壇上找到的程式。因為 Graphics 的 drawImage Method 需要
    //            Image 物件，此函式將 Jpanel 轉成 Image 物件。
    //  關鍵字:   convert Jpanel to Image
    private BufferedImage getImage(Container container) {
        BufferedImage image =
                new BufferedImage(container.getWidth(), container.getHeight(), BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = image.createGraphics();
        container.paint(g2);
        g2.dispose();
        return image;
    }

    private void formMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseClicked
        // TODO add your handling code here:
        /// 公子乖 - 範例程式: 當滑鼠 click 時，將 icon 畫到 mouse 指定的位置
        //ImageIcon soundIcon = createImageIcon("images/sound.gif","sound icon");
        // Graphics g = this.getGraphics();
        //g.drawImage(soundIcon.getImage(), evt.getX(), evt.getY(), this);

        if (beanName == null) {
            return;
        }

        /// 公子乖 -　Serialization 機制
        Class beanClass;
        Object obj = null;
        try {
            beanClass = Class.forName(beanName);
            obj = beanClass.newInstance();
            Image imgObj = getImage((JPanel) obj);
            beanMap.put(Integer.toString(x),
                    new SimpleEntry<Point, SimpleEntry<MyBean, Image>>(new Point(evt.getX(), evt.getY()),
                    new SimpleEntry<MyBean, Image>((MyBean) obj, imgObj)));

        } catch (ClassNotFoundException ex) {
            Logger.getLogger(chatGraphPanel.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            Logger.getLogger(chatGraphPanel.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            Logger.getLogger(chatGraphPanel.class.getName()).log(Level.SEVERE, null, ex);
        }
        //Graphics g = this.getGraphics();
        //g.drawImage(getImage((JPanel) obj), evt.getX(), evt.getY(), this);        
        beanName = null;
        setStatus(DragStatus.PointTo);

        x++;
        repaint();

    }

    protected static ImageIcon createImageIcon(String path,
            String description) {
        java.net.URL imgURL = ChatFrame.class.getResource(path);
        if (imgURL != null) {
            return new ImageIcon(imgURL, description);
        } else {
            System.err.println("Couldn't find file: " + path);
            return null;
        }
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        System.out.println("paintComponent");

        Set set = beanMap.entrySet();
        Iterator iterator = set.iterator();

        while (iterator.hasNext()) {
            Map.Entry me = (Map.Entry) iterator.next();
            String id = (String) me.getKey();
            SimpleEntry<Point, SimpleEntry<MyBean, Image>> entry = (SimpleEntry<Point, SimpleEntry<MyBean, Image>>) me.getValue();
            Point pos = entry.getKey();
            MyBean beanObj = entry.getValue().getKey();
            Image imgObj = entry.getValue().getValue();
            g.drawImage(imgObj, (int) pos.getX(), (int) pos.getY(), this);

            //System.out.println(beanObj);
        }

    }//GEN-LAST:event_formMouseClicked

    /// 公子乖 -　比較每一個 Map 裡的 bean 物件，是否涵蓋座標點。
    private Map.Entry HitTest(Point curPos) {

        Set set = beanMap.entrySet();
        Iterator iterator = set.iterator();

        while (iterator.hasNext()) {
            Map.Entry me = (Map.Entry) iterator.next();
            String id = (String) me.getKey();
            SimpleEntry<Point, SimpleEntry<MyBean, Image>> entry = (SimpleEntry<Point, SimpleEntry<MyBean, Image>>) me.getValue();
            Point pos = entry.getKey();
            MyBean beanObj = entry.getValue().getKey();

            if (curPos.getX() > pos.getX() && curPos.getX() < (pos.getX() + beanObj.getWidth())) {
                if (curPos.getY() > pos.getY() && curPos.getY() < (pos.getY() + beanObj.getHeight())) {
                    /// 公子乖 -　只有作者可以更改自己的圖案。
                    //if (isAuthor(id)) {
                    return me;
                    //}
                }
            }
        }
        return null;
    }

    private void formMouseMoved(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseMoved
        // TODO add your handling code here:
//        if( HitTest(new Point(evt.getX(),evt.getY())) )
//            setCursor(new java.awt.Cursor(java.awt.Cursor.CROSSHAIR_CURSOR));
//        else
//             setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));

        if (status == DragStatus.PointTo) {
            if (HitTest(new Point(evt.getX(), evt.getY())) != null) {
                setStatus(DragStatus.Choose);
            }
        } else if (status == DragStatus.Choose) {
            if (HitTest(new Point(evt.getX(), evt.getY())) == null) {
                setStatus(DragStatus.PointTo);
            }
        }

    }//GEN-LAST:event_formMouseMoved

    private void formMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMousePressed
        // TODO add your handling code here:
        //System.out.println("mouse pressed");
        if (status == DragStatus.Choose) {
            
            Map.Entry me = HitTest(new Point(evt.getX(), evt.getY()));
            if (me == null) {
                return;
            }

            curObj.setId((String)me.getKey());
            System.out.println("id:" + (String)me.getKey());
            SimpleEntry<Point, SimpleEntry<MyBean, Image>> entry = (SimpleEntry<Point, SimpleEntry<MyBean, Image>>) me.getValue();
            curObj.setPos(entry.getKey());
            setStatus(DragStatus.Drag);

        }


    }//GEN-LAST:event_formMousePressed

    private void formMouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseDragged
        // TODO add your handling code here:
        //System.out.println(evt);
        if(status == DragStatus.Drag)
            curObj.setPos(new Point(evt.getX(),evt.getY()));

    }//GEN-LAST:event_formMouseDragged

    private void formMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseReleased
        // TODO add your handling code here:
        if(status == DragStatus.Drag){
            System.out.println( beanMap.get(curObj.id));
            beanMap.get(curObj.getId()).getKey().setLocation(curObj.getPos());
            //System.out.println( beanMap.get(curObj).getKey());
           setStatus(DragStatus.PointTo);
            repaint();
        }
    }//GEN-LAST:event_formMouseReleased

    // Variables declaration - do not modify//GEN-BEGIN:variables
    // End of variables declaration//GEN-END:variables
}
